import type { ID, TableRecord } from "/@/api/models";
import type { FormItemRule, FormValidateHandler, SelectOptionItem } from "/@/types/antd";
import type { TreeSelectProps, DatePickerProps, CascaderProps, SelectProps, ButtonProps } from "ant-design-vue";
import type { PatternKey } from "/@/utils/verify";
import type { OperPermissionType } from "/@/api/aiot/role/models";
import { ref, VNode } from "vue";
import type { PermissionCode } from "/@/api/permissionCode";

export interface CURDDialogEmits {
  /**
   * 打开窗口后触发
   */
  (event: "open", e: CURDModalEvent): void;
  /**
   * 按了确定后发送新增或编辑请求前触发
   */
  (event: "beforeOk", e: CURDModalEvent): void;
  /**
   * 编辑状态打开窗口后赋值更新form model前触发 或 按上一步下一步更新form model前触发
   */
  (event: "beforeUpdateModel", updateModel: TableRecord): void;
}

export interface OperItem<T = TableRecord> {
  label?: boolean | string | ((record: T) => string | boolean);
  //展示为a-button时的type属性
  type?: ButtonProps["type"] | ((record: T) => ButtonProps["type"]);
  //danger属性
  danger?: boolean | ((record: T) => boolean);
  disabledMes?: string | ((record: T) => string);
  handler: (record: T, isCURDDialog?: boolean) => void;
  customSlot?: string;
  showInTable?: boolean;
  showInDialog?: boolean;
  operType?: OperPermissionType;
  permissionCode?: PermissionCode;
  hasPermission?: boolean;
  disabled?: boolean;
}

export enum CURDAction {
  CREATE = "CREATE",
  UPDATE = "UPDATE",
  CHECK = "CHECK",
  DELETE = "DELETE",
}

export interface ShowCURDModalOptions {
  title?: string;
  message?: string;
  action: CURDAction;
  okText?: string;
  record?: TableRecord;
  ids?: ID[];
  recordIndex?: number;
  //是否重新加载数据
  isReloadData?: boolean;
  //是否隐藏上一条下一条按钮
  hideNextPrev?: boolean;
}

export interface CURDModalEvent<T = TableRecord> {
  action?: CURDAction;
  //当前编辑或查看的行记录数据
  record?: T;
  //调用编辑或添加接口前 传入的model对象
  model?: T;
  formItemData: FormItemData<T>[];
}

export interface ExtraComponentHandlerOption {
  curAction: CURDAction;
}

export interface FormItemCustomComponentExpose {
  validate?: () => boolean;
  clear?: () => void;
}

export interface FormItemData<T = TableRecord> {
  label?: string;
  //查看模式下的label
  checkLabel?: string;
  //label后的提示信息
  labelDes?: string;
  key: keyof T | "_subTitle";
  //当key为"_subTitle"，该字段生效，表示该标题项放在哪一个字段的前面
  beforeKey?: keyof T;
  subTitle?: string;
  type?: FormItemComponentType;
  text?: string;
  getText?: (value: any, record: T) => string | number;
  //在查看模式时 显示的文字key
  textKey?: string;
  //在查看模式时 显示的文字item的value key
  valueKey?: string;
  loading?: boolean;
  getData?: (e: { action: CURDAction; item: FormItemData; params?: any }) => Promise<any>;
  pattern?: PatternKey | RegExp;
  max?: number;
  min?: number;
  required?: boolean;
  requiredMes?: string;
  //为true则不渲染dom
  hide?: boolean;
  //控制dom的v-show
  show?: boolean;
  customComponent?: VNode;
  extraComponent?: VNode | ((option: ExtraComponentHandlerOption) => VNode | null);
  customComponentRef?: FormItemCustomComponentExpose;
  //执行更新或添加接口前调用 处理返回覆盖对应字段值
  //表单值转化为服务器接口需要的值
  formValueToInterValue?: (value: any, model: T, el: FormItemData) => any;
  //服务器接口返回来的值转化为表单值
  interValueToFormValue?: (value: any, model: T, el: FormItemData) => any;
  props?: {
    placeholder?: string;
    //antdv组件props
    //公共
    disabled?: boolean;
    //a-select
    options?: SelectProps["options"];
    mode?: string;
    //a-textarea
    rows?: number;
    // a-upload
    max?: number;
    //a-cascader
    loadData?: CascaderProps["loadData"];
    dropdownClassName?: string;
    //a-range-picker
    disabledDate?: DatePickerProps["disabledDate"];
    //ImgUpload
    manual?: boolean;
    //a-tree-select
    treeData?: TreeSelectProps["treeData"];
    fieldNames?: TreeSelectProps["fieldNames"];
    data?: TableRecord[];
  } & Record<string, any>;
}

export type ModelRules<T = any> = (keyof T | { [key: string]: FormItemRule[] })[];

export enum FormItemComponentType {
  TEXT = "text",
  TEXTAREA = "textarea",
  SELECT = "select",
  DATEPICKER = "datePicker",
  CHECKBOX = "checkbox",
  CASCADER = "cascader",
  RANGEPICKER = "rangePicker",
  IMGUPLOAD = "imgUpload",
  TREESELECT = "treeSelect",
  PASSWORD = "password",
  SWITCH = "switch",
  RADIO = "radio",
  EDITOR = "editor",
  FILEUPLOAD = "fileUpload",
}

export function isSelectComponent(type: FormItemComponentType) {
  return [FormItemComponentType.SELECT, FormItemComponentType.CASCADER, FormItemComponentType.TREESELECT].includes(
    type
  );
}

export interface DynamicFormExpose<T = TableRecord> {
  /**
   * 根据formItem key和option value找到整个optionItem
   * @param formItemKey FormItem的字段值
   * @param optionValue optionItem的value值
   */
  getOptionItemByValue: (formItemKey: keyof T, optionValue: string | number) => SelectOptionItem | undefined;
  /**
   * 重新加载某个FormItemComponent的数据
   * @param formItemKey FormItem的字段值
   * @param params 加载接口所需的参数
   */
  reloadFormItemComponentData: (formItemKey: keyof T, params?: any) => void;
  /**
   * 重置表单字段值
   */
  resetFields: () => void;
  /**
   * 验证表单
   */
  validate: FormValidateHandler;
  validateComponent: () => Promise<boolean>;
  /**
   * 获取内部表单字段配置数据
   */
  getFormItemData: () => FormItemData[];
  /**
   * 初始化需要异步加载数据的组件，比如Select
   */
  initFormItemComponentData: () => Promise<boolean[]>;
  /**
   * 动态设置某个字段是否必填
   */
  setFieldRquired: (key: keyof T, required: boolean) => void;
  /**
   * 隐藏或显示某个字段
   */
  toggleField: (key: keyof T, hide: boolean) => void;
}

export interface CURDDialogExpose<T = TableRecord> {
  isOpen: () => boolean;
  getOptionItemByValue: DynamicFormExpose<T>["getOptionItemByValue"];
  reloadFormItemComponentData: DynamicFormExpose<T>["reloadFormItemComponentData"];
  setFieldRquired: DynamicFormExpose<T>["setFieldRquired"];
  toggleField: DynamicFormExpose<T>["toggleField"];
  getFormContainer: () => HTMLDivElement | undefined;
}
